package com.hframe.filter;

import com.hframe.FrameInit;
import com.hframe.rights.RightsStruct;
import com.hframe.type.TArray;
import org.apache.log4j.Logger;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;

public class LoginFilter implements Filter {
    static Logger log = Logger.getLogger(LoginFilter.class);
    public static final String PreviousURL = "PreviousURL";
    protected String loginURL = null;
    protected String sessionUser = null;
    protected String rightsURL = null;
    protected ArrayList<String> mPass = new ArrayList<>();

    public LoginFilter() {
        mPass.add(".js");
        mPass.add(".css");
        mPass.add(".eot");
        mPass.add(".svg");
        mPass.add(".ttf");
        mPass.add(".woff");
    }

    @Override
    public void destroy() {
    }


    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        HttpSession ses = req.getSession();
//        String url = req.getRequestURI().substring(req.getContextPath().length());
        String url = ((HttpServletRequest) request).getServletPath();
        do {
            if (null != ses.getAttribute(sessionUser))
                break;

            if (null == loginURL || null == sessionUser)
                break;

            String tempUrl = url.toLowerCase();
            if (url.equals(loginURL) || isPass(tempUrl)) {
                chain.doFilter(request, response);
                return;
            }

            if (isPrevious(request, tempUrl)) {
                String query = ((HttpServletRequest) request).getQueryString();
                ses.setAttribute(PreviousURL, req.getRequestURI() + null == query ? "" : "?" + query);
            }

            notLogin(req, res);
            return;
        } while (false);


        if (notRights(req, res, ses, url)) {
            chain.doFilter(request, response);
        }
    }

    private boolean isPass(String tempUrl) {
        for (String item : mPass) {
            if (tempUrl.endsWith(item))
                return true;
        }
        return false;
    }


    protected boolean notRights(HttpServletRequest req, HttpServletResponse res, HttpSession ses, String url) throws IOException {
        if (!rightsFilter(ses, getRights(), url)) {
            if ("XMLHttpRequest".equals(req.getHeader("X-Requested-With"))) {
                res.setStatus(403);
            } else {
                if (null != rightsURL) {
                    res.sendRedirect(req.getContextPath() + rightsURL);
                } else {
                    res.setStatus(403);
                }
            }
            return false;
        }
        return true;
    }

    protected void notLogin(HttpServletRequest req, HttpServletResponse res) throws IOException {
        if ("XMLHttpRequest".equals(req.getHeader("X-Requested-With"))) {
            res.setHeader("NotLoginJmpURL", req.getContextPath() + loginURL);
            res.setStatus(401);
        } else {
            if (null != loginURL) {
                res.sendRedirect(req.getContextPath() + loginURL);
            } else {
                res.setStatus(401);
            }
        }
    }

    protected boolean rightsFilter(HttpSession session, TArray<RightsStruct.DataStruct> rights, String url) {
        for (RightsStruct.DataStruct item : rights.get()) {
            if (url.indexOf(item.url.get()) == 0) {
                boolean rig = isRightsId(session, item.id.get());
                if (!rig)
                    return false;
                else if (item.item.isEmpty())
                    return true;
                return rightsFilter(session, item.item, url);
            }
        }
        return true;
    }

    /**
     * 判断当前权限是否有效
     *
     * @param session
     * @param rightsId
     * @return
     */
    protected boolean isRightsId(HttpSession session, String rightsId) {

        return false;
    }

    /**
     * 获得权限配置
     *
     * @return
     */
    protected TArray<RightsStruct.DataStruct> getRights() {
        return RightsStruct.get().getRights();
    }

    @Override
    public void init(FilterConfig fConfig) throws ServletException {
        this.loginURL = fConfig.getInitParameter("LoginURL");
        this.sessionUser = fConfig.getInitParameter("SessionUser");
        this.rightsURL = fConfig.getInitParameter("RightsUrl");

        String pass = fConfig.getInitParameter("PassSuffix");
        if (null != pass) {
            mPass.clear();
            String[] suffixs = pass.split(",");
            for (String item : suffixs)
                mPass.add(item);
        }
    }

    /**
     * 根据后缀名,判断是否是要跳转的路径
     *
     * @param request
     * @param url
     * @return
     */
    private boolean isPrevious(ServletRequest request, String url) {
        FilterRegistration regs = request.getServletContext().getFilterRegistration(FrameInit.SkipFilterName);
        if (null != regs) {
            for (String item : regs.getUrlPatternMappings()) {
                // System.out.println(item.substring(1));
                if (item.length() > 1 && url.endsWith(item.toLowerCase().substring(1)))
                    return true;
            }
        }
        return false;
    }

}
